package com.sojson.util.gzip.zip;

import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * ZIP压缩工具类
 * 
 * @author liu
 * @date 2022-08-03
 */
@Slf4j
public class ZipUtil {

    /**
     * 将字节流添加到压缩包
     * 
     * @param path      文件路径
     * @param fileName  文件名
     * @param bytes     字节流
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String path, String fileName, byte[] bytes) throws Exception {
        Map<String, byte[]> hashMap = new HashMap<>();
        hashMap.put(path + "/" + fileName, bytes);
        return getBytes(hashMap);
    }

    /**
     * 将字节流添加到压缩包
     * 
     * @param path      文件路径
     * @param fileName  文件名
     * @param bytes     字节流
     * @return
     * @throws Exception
     */
    public static ByteArrayOutputStream getOutputStream(String path, String fileName, byte[] bytes) throws Exception {
        Map<String, byte[]> hashMap = new HashMap<>();
        hashMap.put(path + "/" + fileName, bytes);
        return getOutputStream(hashMap);
    }

    /**
     * 将字节流添加到压缩包
     * 
     * @param bytes 字节流集合(key:文件路径+文件名,val:字节流)
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(Map<String, byte[]> bytes) throws Exception {
        ByteArrayOutputStream outputStream = null;
        try {
            outputStream = getOutputStream(bytes);
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return outputStream.toByteArray();
    }

    /**
     * 将字节流添加到压缩包
     * 
     * @param bytes 字节流集合(key:文件路径+文件名,val:字节流)
     * @return
     * @throws Exception
     */
    public static ByteArrayOutputStream getOutputStream(Map<String, byte[]> bytes) throws Exception {
        ByteArrayOutputStream outputStream = null;
        ZipOutputStream zip = null;
        try {
            outputStream = new ByteArrayOutputStream();
            zip = new ZipOutputStream(outputStream);
            Set<Entry<String, byte[]>> entrySet = bytes.entrySet();
            for (Entry<String, byte[]> entry : entrySet) {
                zip.putNextEntry(new ZipEntry(entry.getKey()));
                IOUtils.write(entry.getValue(), zip);
            }
            zip.flush();
        } finally {
            if (zip != null) {
                try {
                    zip.closeEntry();
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
                try {
                    zip.close();
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return outputStream;
    }

}